<template>
  <div ref="container" class="scene-container"></div>
  <audio ref="collisionSound" src="/sounds/collision.mp3" preload="auto"></audio>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
import * as THREE from 'three'
import { PointerLockControls } from 'three/examples/jsm/controls/PointerLockControls'

const container = ref(null)
const collisionSound = ref(null)
let camera, scene, renderer, controls
let moveForward = false
let moveBackward = false
let moveLeft = false
let moveRight = false
let canJump = true
let velocity = new THREE.Vector3()
let direction = new THREE.Vector3()

// 物理参数
const GRAVITY = 30.0
const JUMP_FORCE = 12.0
const MOVEMENT_SPEED = 0.2
let isOnGround = true

// 碰撞检测相关
let objects = []
const raycaster = new THREE.Raycaster()
const playerRadius = 1

// 播放碰撞音效
const playCollisionSound = () => {
  if (collisionSound.value) {
    collisionSound.value.currentTime = 0
    collisionSound.value.play()
  }
}

// 检查碰撞
const checkCollision = (position, direction, distance) => {
  raycaster.set(position, direction)
  const intersects = raycaster.intersectObjects(objects)
  return intersects.length > 0 && intersects[0].distance < distance
}

// 初始化场景
const init = () => {
  scene = new THREE.Scene()
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  
  renderer = new THREE.WebGLRenderer()
  renderer.setSize(window.innerWidth, window.innerHeight)
  container.value.appendChild(renderer.domElement)

  // 添加地面
  const groundGeometry = new THREE.PlaneGeometry(100, 100)
  const groundMaterial = new THREE.MeshBasicMaterial({ 
    color: 0x808080,
    side: THREE.DoubleSide 
  })
  const ground = new THREE.Mesh(groundGeometry, groundMaterial)
  ground.rotation.x = -Math.PI / 2
  scene.add(ground)
  objects.push(ground)

  // 添加立方体
  for(let i = 0; i < 10; i++) {
    const geometry = new THREE.BoxGeometry(2, 2, 2)
    const material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff })
    const cube = new THREE.Mesh(geometry, material)
    cube.position.set(
      Math.random() * 40 - 20,
      1,
      Math.random() * 40 - 20
    )
    scene.add(cube)
    objects.push(cube)
  }

  camera.position.y = 2
  controls = new PointerLockControls(camera, document.body)

  container.value.addEventListener('click', () => {
    controls.lock()
  })
}

// 键盘控制
const onKeyDown = (event) => {
  switch (event.code) {
    case 'ArrowUp':
    case 'KeyW':
      moveForward = true
      break
    case 'ArrowDown':
    case 'KeyS':
      moveBackward = true
      break
    case 'ArrowLeft':
    case 'KeyA':
      moveLeft = true
      break
    case 'ArrowRight':
    case 'KeyD':
      moveRight = true
      break
    case 'Space':
      if (isOnGround) {
        velocity.y = JUMP_FORCE
        isOnGround = false
      }
      break
  }
}

const onKeyUp = (event) => {
  switch (event.code) {
    case 'ArrowUp':
    case 'KeyW':
      moveForward = false
      break
    case 'ArrowDown':
    case 'KeyS':
      moveBackward = false
      break
    case 'ArrowLeft':
    case 'KeyA':
      moveLeft = false
      break
    case 'ArrowRight':
    case 'KeyD':
      moveRight = false
      break
  }
}

// 修改动画循环
const animate = () => {
  requestAnimationFrame(animate)
  
  if (controls.isLocked) {
    const delta = 0.016

    // 应用重力
    velocity.y -= GRAVITY * delta
    camera.position.y += velocity.y * delta

    if (camera.position.y <= 2) {
      velocity.y = 0
      camera.position.y = 2
      isOnGround = true
    }

    // 水平移动
    velocity.x = 0
    velocity.z = 0

    direction.z = Number(moveForward) - Number(moveBackward)
    direction.x = Number(moveRight) - Number(moveLeft)
    direction.normalize()

    // 计算预期移动位置
    const moveX = direction.x * MOVEMENT_SPEED
    const moveZ = direction.z * MOVEMENT_SPEED

    // 检查四个方向的碰撞
    const currentPosition = camera.position.clone()
    const forwardDirection = new THREE.Vector3(0, 0, -1).applyQuaternion(camera.quaternion)
    const rightDirection = new THREE.Vector3(1, 0, 0).applyQuaternion(camera.quaternion)

    let canMoveForward = true
    let canMoveRight = true

    // 前后方向碰撞检测
    if (moveForward || moveBackward) {
      const checkDirection = moveForward ? forwardDirection : forwardDirection.negate()
      if (checkCollision(currentPosition, checkDirection, playerRadius + Math.abs(moveZ))) {
        canMoveForward = false
        playCollisionSound()
      }
    }

    // 左右方向碰撞检测
    if (moveLeft || moveRight) {
      const checkDirection = moveRight ? rightDirection : rightDirection.negate()
      if (checkCollision(currentPosition, checkDirection, playerRadius + Math.abs(moveX))) {
        canMoveRight = false
        playCollisionSound()
      }
    }

    // 应用移动
    if (canMoveForward && (moveForward || moveBackward)) {
      controls.moveForward(-moveZ)
    }
    if (canMoveRight && (moveLeft || moveRight)) {
      controls.moveRight(-moveX)
    }
  }

  renderer.render(scene, camera)
}

// 窗口大小调整
const onWindowResize = () => {
  camera.aspect = window.innerWidth / window.innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(window.innerWidth, window.innerHeight)
}

onMounted(() => {
  init()
  animate()
  
  window.addEventListener('resize', onWindowResize)
  document.addEventListener('keydown', onKeyDown)
  document.addEventListener('keyup', onKeyUp)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize', onWindowResize)
  document.removeEventListener('keydown', onKeyDown)
  document.removeEventListener('keyup', onKeyUp)
})
</script>

<style scoped>
.scene-container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.scene-container canvas {
  display: block;
  width: 100%;
  height: 100%;
}
</style> 